package netty.demo;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

import static netty.demo.ByteBufferUtil.*;
/**
 * 功能描述:<br>
 * 〈〉
 *
 * @author wxfu
 * @create 2021/11/7
 * @since 1.0.0
 */
@Slf4j
public class Server {
    public static void main(String[] args) throws IOException {
        // 1.创建 selector , 管理多个 channel
        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        
        // 2.建立 selector 和 channel 的联系 (注册)
        // SelectionKey 就是将来事件发生后,通过他可以知道事件和哪个channel的事件
        SelectionKey sscKey = ssc.register(selector, 0, null);
        // key 只关注 accept 事件
        sscKey.interestOps(SelectionKey.OP_ACCEPT);
        log.debug("register  key :{}",sscKey);
        
        ssc.bind(new InetSocketAddress(8080));
        while (true) {
            //3. select 方法 , 没有事件发生,线程阻塞,有事件,线程才会恢复运行
            selector.select();
            // 4. 处理事件 , selectorKeys 内部包含了所有发生的事件
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                
                SelectionKey key = iterator.next();
                log.debug("key  key :{}",key);
                if (key.isAcceptable()) {
                    ServerSocketChannel cancel = (ServerSocketChannel) key.channel();
                    SocketChannel accept = cancel.accept();
                    accept.configureBlocking(false);
                    //管理channel
                    SelectionKey register = accept.register(selector, 0, null);
                    //关注事件
                    register.interestOps(SelectionKey.OP_ACCEPT);
                    log.debug("{}",accept);
                }else if (key.isReadable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer byteBuffer = ByteBuffer.allocate(16);
                    channel.read(byteBuffer);
                    byteBuffer.flip();
                    debugRead(byteBuffer);
                }
            
             
            }
        }
    }
}
